package com.security.one_way_encry.hmac;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.tls.MACAlgorithm;
import org.bouncycastle.jcajce.provider.digest.GOST3411;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

/**
 * @ClassName TestHMAC
 * @Description HMAC 算法
 * @Detail     1、该算法跟MD5、sha算法一样，都是不可逆的
 *              2、相同的字符串通过相同的HMAC算法得到的加密串是相同的
 * @Author MyPC
 * @Date 2020/9/23
 * @Version 1.0
 */
public class TestHMAC {
    /**
     * MAC算法可选以下多种算法
     *
     * <pre>
     * HmacMD5
     * HmacSHA1
     * HmacSHA256
     * HmacSHA384
     * HmacSHA512
     * </pre>
     */
    public static final String KEY_MAC = "HmacMD5";
    public static final String src = "hello";

    public static void main(String[] args) throws Exception {
        String hello = encryptHMAC("hello");
        System.out.println(hello);
        bcHmacMD5();
        apacheHmacMD5();
        apacheHmacSha1();
        apacheHmacSha224();
        apacheHmacSha256();
        apacheHmacSha384();
        apacheHmacSha512();
    }

    /**
     * 使用java实现
     * @param key
     * @return
     * @throws Exception
     */
    public static String encryptHMAC(String key) throws Exception {
        //初始化KeyGenerator
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
        SecretKey secretKey = keyGenerator.generateKey();
        //1、获取密钥
        //获取固定密钥
        byte[] bytes = Hex.decodeHex(new char[]{'1', '2', '3', '4', '5', '6'});
        //还原密钥
        SecretKey secretKeySpec = new SecretKeySpec(bytes, KEY_MAC);
        //创建Mac对象
        Mac mac = Mac.getInstance(secretKeySpec.getAlgorithm());
        //初始化Mac
        mac.init(secretKeySpec);
        //执行摘要
        byte[] code = mac.doFinal(key.getBytes());
        return Hex.encodeHexString(code);
    }

    /**
     * 用bouncy castle实现
     */
    public static void bcHmacMD5()
    {
        HMac hmac = new HMac(new MD5Digest());
        // 必须是16进制的字符，长度必须是2的倍数
        hmac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("123456")));
        hmac.update(src.getBytes(), 0, src.getBytes().length);

        // 执行摘要
        byte[] hmacMD5Bytes = new byte[hmac.getMacSize()];
        hmac.doFinal(hmacMD5Bytes, 0);
        System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(hmacMD5Bytes));

    }

    /**
     * 用 apache 实现
     */
    public static void apacheHmacMD5() throws  DecoderException {
        Mac initializedMac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_MD5, Hex.decodeHex(new char[]{'1', '2', '3', '4', '5', '6'}));
        byte[] bytes = initializedMac.doFinal(src.getBytes());
        System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(bytes));

    }
    /**
     * 用 apache 实现
     */
    public static void apacheHmacSha1() throws  DecoderException {
        Mac initializedMac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_SHA_1, Hex.decodeHex(new char[]{'1', '2', '3', '4', '5', '6'}));
        byte[] bytes = initializedMac.doFinal(src.getBytes());
        System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(bytes));

    }

    /**
     * 用 apache 实现
     */
    public static void apacheHmacSha224() throws  DecoderException {
        Mac initializedMac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_SHA_224, Hex.decodeHex(new char[]{'1', '2', '3', '4', '5', '6'}));
        byte[] bytes = initializedMac.doFinal(src.getBytes());
        System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(bytes));

    }

    /**
     * 用 apache 实现
     */
    public static void apacheHmacSha256() throws  DecoderException {
        Mac initializedMac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_SHA_256, Hex.decodeHex(new char[]{'1', '2', '3', '4', '5', '6'}));
        byte[] bytes = initializedMac.doFinal(src.getBytes());
        System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(bytes));

    }

    /**
     * 用 apache 实现
     */
    public static void apacheHmacSha384() throws  DecoderException {
        Mac initializedMac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_SHA_384, Hex.decodeHex(new char[]{'1', '2', '3', '4', '5', '6'}));
        byte[] bytes = initializedMac.doFinal(src.getBytes());
        System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(bytes));

    }

    /**
     * 用 apache 实现
     */
    public static void apacheHmacSha512() throws  DecoderException {
        Mac initializedMac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_SHA_512, Hex.decodeHex(new char[]{'1', '2', '3', '4', '5', '6'}));
        byte[] bytes = initializedMac.doFinal(src.getBytes());
        System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(bytes));

    }



}
